<?php
/**
 * 文件存储
 */
class Storage
{
	public static function get($key, $withdata=false)
    {
    	if($withdata)
    	{
    		$r	=	Db::get(__CLASS__)->select()->where(array('key'=>$key))->getOne();
    		if($r)
    		{
    			$r['data']	=	self::getContent($key);
    			return $r;
    		}
    		else
    			return false;
    	}
    	else{
    		return Db::get(__CLASS__)->select()->where(array('key'=>$key))->getOne();
    	}
    }

    public static function getList($where, $s=0, $l=0)
    {
        return Db::get(__CLASS__)->select()->where($where)->order('`key` DESC')->limit($s, $l)->getAll();
    }
    public static function count($where)
    {
        return Db::get(__CLASS__)->count()->where($where)->getCol();
    }

    /**
     * 添加一条存储
     *
     * @param $data		Array keys: name,c_type,type,mode
     * @param $file_data
     * @return mixed false|array
     */
    public static function add($data, $file_data)
    {
    	//save file content
    	$key	=	self::genKey();
    	$_path	=	self::key2path($key);
    	$path	=	app_cfg('setting','store_path'). $_path;
    	if(!file_exists(dirname($path))){
    		mkdir(dirname($path), 0755, true);
    	}
    	file_put_contents($path, $file_data);
    	
    	//save storage info
    	$data['key']	=	$key;
    	$data['path']	=	$_path;
    	$data['size']	=	strlen($file_data);
    	$data['addtime']	=	time();
        
        if(Db::get(__CLASS__)->insert($data)->exec())
        {
        	return $data;
        }
        else
        {
        	try{
				unlink($path);
			}
			catch(Exception $_){}
        	return false;
        }
    }
    public static function update($key, $data, $file_data=null)
    {
    	$data	=	array_intersect_key($data, array_flip(array('name','c_type','type','mode')));
    	
    	if(null!==$file_data)
    	{
	    	//save file content
	    	$store	=	self::get($key, false);
	    	@file_put_contents(app_cfg('setting','store_path'). $store['path'], $file_data);
	    	
	    	$data['size']	=	strlen($file_data);
    	}

		if($data){
			if(Db::get(__CLASS__)->update($data)->where(array('key'=>$key))->exec()){
				return $data;
			}
			else{
				return false;
			}
		}
		else{
			return true;
		}
    }
    public static function delete($key)
    {
    	$store	=	self::get($key, false);
		try{
			if(unlink(app_cfg('setting','store_path'). $store['path'])){
				return Db::get(__CLASS__)->delete()->where(array('key'=>$key))->exec();
			}
		}
		catch(Exception $_){
			return false;
		}
    	return false;
    }
	
    /**
     * 支持由storage.key生成(或叫取得)文件存储路径，不负责检查文件是否存在
     *
     * @param $key
     * @return string
     */
    public static function key2path($key)
    {
    	//存储策略的节点，待以后升级时使用
    	//$ver	=	substr($key, 0, 2);
    	return sprintf('/%s/%s/%s/%s', substr($key, 2,1), substr($key, 3, 2), substr($key, 5, 3), substr($key, 8));
    }
    
    /**
     * 生成唯一的key
     *
     * @return unknown_type
     */
    public static function genKey($ver='10')
    {
    	$key	=	uniqid();
    	return $ver.strrev(substr($key, -3).substr($key, 0, -3));
    }
    
    /**
     * 非严格方式读取方式，未取storage.path；为加速读取操作，直接从storage.key算出目录
     *
     * @return mixed false|string
     */
    public static function getContent($key)
    {
    	$path	=	app_cfg('setting','store_path'). self::key2path($key);
    	return file_exists($path) ? file_get_contents($path) : false;
    }
    
    
}

?>